package com.uxsino.simo.indicator.retractor;

import com.uxsino.commons.utils.config.ConfigProp;
import com.uxsino.simo.networkentity.EntityInfo;
import com.uxsino.simo.query.QueryContext;
import com.uxsino.simo.query.QueryTemplate;

import java.util.*;
import java.util.Map.Entry;

public class SNMPVLANCiscoRetractor extends ListValueRetractor {

    @ConfigProp(name = "child_field")
    public String child_field;

    @ConfigProp(name = "vlan_id_field")
    public String vlan_id_field;

    @ConfigProp(name = "vlan_if_index_id_fields")
    public String vlan_if_index_id_fields;

    @ConfigProp(name = "exclude_vlan_id")
    public String exclude_vlan_id;

    @ConfigProp(name = "id_field_key")
    public String id_field_key;

    public SNMPVLANCiscoRetractor() {
        super();
    }

    @Override
    public Object doRetract(EntityInfo entity, QueryContext ctxt, QueryTemplate qt, Object obj) {
        ArrayList<Map<String, Object>> records = new ArrayList<Map<String, Object>>();
        if (obj == null) {
            return records;
        }
        @SuppressWarnings("unchecked")
        Map<String, Map<String, String>> map = (Map<String, Map<String, String>>) obj;
        Map<String, String> ifDescMap = getIfDescMap(map);
        Map<String, List<String>> vlanIfDescMap = getVlanIfDescMap(map, ifDescMap);

        Set<String> excludeKeySet = new HashSet<>();
        excludeKeySet.add(child_field);
        String[] ex = vlan_if_index_id_fields.split(",");
        for (String e : ex) {
            excludeKeySet.add(e);
        }

        for (Entry<String, String> nameEntry : map.get(vlan_id_field).entrySet()) {
            Map<String, Object> itemMap = new HashMap<>();
            String signStr = nameEntry.getKey().trim();
            if (signStr.endsWith(".")) {
                signStr = signStr.substring(0, signStr.length() - 1);
            }
            int ei = signStr.lastIndexOf(".");
            String sign = signStr.substring(ei + 1);

            itemMap.put(id_field_key, sign);
            for (ColumnEntry columnEntry : columnEntries) {
                if (map.containsKey(columnEntry.index)) {
                    if (!excludeKeySet.contains(columnEntry.index)) {
                        Map<String, String> innerMap = map.get(columnEntry.index);
                        for (Entry<String, String> innerEntry : innerMap.entrySet()) {

                            String innerKey = innerEntry.getKey();
                            if (innerKey.endsWith(".")) {
                                innerKey = innerKey.substring(0, innerKey.length() - 1);
                            }
                            int e = innerKey.lastIndexOf(".");
                            String tail = innerKey.substring(e + 1);
                            if (tail.equals(sign)) {
                                itemMap.put(columnEntry.field.getName(),
                                    columnEntry.retractor.retract(entity, ctxt, qt, innerEntry.getValue()));
                                break;
                            }

                        }

                    }
                }
                if (columnEntry.index.equals(child_field)) {
                    if (vlanIfDescMap.get(sign) != null) {
                        itemMap.put(columnEntry.field.getName(), String.join(",", vlanIfDescMap.get(sign)));
                    }
                }
            }
            records.add(itemMap);
        }
        return records;
    }

    private Map<String, String> getIfDescMap(Map<String, Map<String, String>> dataMap) {
        Map<String, String> result = new HashMap<>();
        for (Entry<String, String> entry : dataMap.get(child_field).entrySet()) {
            String ck = entry.getKey();
            if (ck.endsWith(".")) {
                ck = ck.substring(0, ck.length() - 1);
            }
            int cei = ck.lastIndexOf(".");
            String ce = ck.substring(cei + 1);
            result.put(ce, entry.getValue());
        }
        return result;
    }

    private Map<String, List<String>> getVlanIfDescMap(Map<String, Map<String, String>> dataMap,
        Map<String, String> ifDescMap) {
        Map<String, List<String>> result = new HashMap<>();
        String[] fields = vlan_if_index_id_fields.split(",");
        for (String field : fields) {
            if (dataMap.get(field) != null) {
                for (Entry<String, String> indexEntry : dataMap.get(field).entrySet()) {
                    if (indexEntry.getValue().equals(exclude_vlan_id)) {
                        continue;
                    }
                    String k = indexEntry.getKey();
                    if (k.endsWith(".")) {
                        k = k.substring(0, k.length() - 1);
                    }
                    int lastDotIndex = k.lastIndexOf(".");
                    String ifIndex = k.substring(lastDotIndex + 1);
                    String ifDesc = ifDescMap.getOrDefault(ifIndex, null);
                    if (ifDesc == null) {
                        continue;
                    }
                    if (!result.containsKey(indexEntry.getValue())) {
                        result.put(indexEntry.getValue(), new ArrayList<String>());
                    }
                    result.get(indexEntry.getValue()).add(ifDesc);
                }
            }
        }
        return result;
    }

}
